# 程序入口
from Tools import *
import PrintTree
import os
import openpyxl
import threading
import time


def multi_threading(tools, fun_name, t, l):
    """

    :param tools:工具类
    :param fun_name: 使用的方法名
    :param t: 循环次数
    :param l: 线程锁
    :return:
    """
    d = dict()
    for k in tools.sample_dict_start:
        d[k] = 0
    for i in range(t):
        mtx = tools.get_distance_matrix(rdm=True)  # 表示随机n列生成距离矩阵
        tree = tools.clustering_algorithm(mtx, fun=fun_name)  # 生成元组树
        tools.update_dict_d(tree, d)
    # print(d)
    l.acquire()
    for j in tools.sample_dict_result:
        tools.sample_dict_result[j] += d[j]
    l.release()


if __name__ == '__main__':
    tools = Tools()  # 创建工具类
    path1 = tools.start()  # 开始工具类,path1为用户输入路径

    sample_matrix = tools.get_distance_matrix()  # 样本原始矩阵，不进行随机列

    while True:
        print("请输入聚类方法(1 或 2):")
        print("1.UPGMA    2.NJ")
        fun_name = input()
        try:
            fun_name = int(fun_name)
        except ValueError as ve:
            print(ve, "请输入正确选项!")
            continue
        if fun_name == 1:
            fun_name = "UPGMA"
            break
        elif fun_name == 2:
            fun_name = "NJ"
            break
        else:
            print("请输入正确的选项")
            continue
    sample_tree_tuple = tools.clustering_algorithm(sample_matrix, fun=fun_name)  # 对样本矩阵进行聚类算法操作
    tools.get_sample_dict(sample_tree_tuple)

    while True:
        path2 = input("请输入生成文件存放路径（windows路径)：")  # path2为用户输出路径
        path2 = path2.replace("\\", "/")
        try:
            filename = path2 + "/test.txt"
            f = open(filename, 'w')
        except FileNotFoundError as e:
            print(e, "文件路径输入失败！")
            continue
        f.close()
        os.remove(path2 + "/test.txt")
        break  # 文件路径正确，退出循环

    count = 1  # 计数
    sample = path2 + "/sample"  # 生成样本文件夹
    while True:
        sample_file = sample + str(count)
        if os.path.exists(sample_file):
            count += 1
        else:
            break
    os.mkdir(sample_file)

    wb = openpyxl.Workbook()
    sheet1 = wb.active
    sheet1.title = "Distance"  # 表一，距离矩阵
    l0 = tools.get_dis_sim_matrix(sample_matrix, False)
    for i in l0:
        sheet1.append(i)
    sheet2 = wb.create_sheet("Similarity")  # 表二，相似矩阵
    l1 = tools.get_dis_sim_matrix(sample_matrix, True)
    for i in l1:
        sheet2.append(i)
    l2 = path1.split("/")
    excel_file_name = sample_file + '/' + l2[-1]
    excel_file_name = excel_file_name.replace(".xlsx", '') + "-jacc.xlsx"
    wb.save(excel_file_name)

    # 1000次bootstrap
    while True:
        times = input("请输入bootstrap次数：")
        try:
            times = int(times)
        except ValueError as c:
            print(c, "输入有误请重新输入！")
            continue
        if times <= 0:
            print("输入不能为0和负数，请重新输入:")
        else:
            break
    while True:
        thread_count = input("请输入使用线程数：")
        try:
            thread_count = int(thread_count)
        except ValueError as c:
            print(c, "输入有误请重新输入！")
            continue
        if thread_count <= 0:
            print("输入不能为0和负数，请重新输入:")
        elif thread_count > 20:
            print("输入不能超过20，请重新输入:")
        else:
            break
    # i = 0
    # while i < times:
    #     mtx = tools.get_distance_matrix(rdm=True)  # 表示随机n列生成距离矩阵
    #     tree = tools.clustering_algorithm(mtx, fun=fun_name)  # 生成元组树
    #     tools.update_dict(tree)  # 更新样本字典
    #     i += 1
    lock = threading.Lock()
    thread_pool = list()    # 线程组
    start_time = time.time()    # 记录开始时间
    for i in range(thread_count):
        td = threading.Thread(target=multi_threading, args=(tools, fun_name, int(times/thread_count), lock))
        thread_pool.append(td)
        td.start()
    for i in thread_pool:
        i.join()
    end_time = time.time()      # 记录结束时间
    print(end_time-start_time, '秒')
    #
    # print(".............................")
    # print(tools.sample_dict_result)
    st = tools.get_Nwk_str(sample_tree_tuple, times)
    st = st.replace(":-1.0", ";")
    f = open(excel_file_name.replace(".xlsx", "_" + fun_name + "_tree.nwk"), 'w')
    f.write(st)
    f.flush()
    f.close()
    PrintTree.print_tree_tuple(sample_tree_tuple, sample_file + "/tree.html")
